package stc.skymobi.netty.closure;

import org.apache.commons.collections.Closure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stc.skymobi.ebus.EventBus;

import java.util.*;

public class EventDispatchClosure implements Closure {

    private static final Logger logger =
            LoggerFactory.getLogger(EventDispatchClosure.class);

    private EventBus eventBus;

    private Map<Class<?>, String> events = new HashMap<Class<?>, String>();

    private Closure nulleventHandler = null;

    /**
     * @return the nulleventHandler
     */
    public Closure getNulleventHandler() {
        return nulleventHandler;
    }

    /**
     * @param nulleventHandler the nulleventHandler to set
     */
    public void setNulleventHandler(Closure nulleventHandler) {
        this.nulleventHandler = nulleventHandler;
    }

    public Collection<String> getTypeEvents() {
        Collection<String> ret = new ArrayList<String>();

        for (Map.Entry<Class<?>, String> entry : events.entrySet()) {
            ret.add(entry.getKey().getSimpleName() + "<-->" + entry.getValue());
        }

        return ret;
    }

    public Map<Class<?>, String> getEvents() {
        return Collections.unmodifiableMap(events);
    }

    public void setEvents(Map<Class<?>, String> events) {
        this.events.clear();

        for (Map.Entry<Class<?>, String> entry : events.entrySet()) {
            if (null != entry.getValue()) {
                this.events.put(entry.getKey(), entry.getValue());
            }
        }
    }


    /* (non-Javadoc)
     * @see org.apache.commons.collections.Closure#execute(java.lang.Object)
     */
    public void execute(Object input) {
        if (null == input) {
            return;
        }

        String event = events.get(input.getClass());
        if (null == event) {
            if (null != nulleventHandler) {
                nulleventHandler.execute(input);
            } else {
                logger.warn("can't found event for " + input + ", just ignore.");
            }
            return;
        }

        if (logger.isDebugEnabled()) {
            logger.debug("fire event [" + event + "] <--> " + input);
        }
        eventBus.fireEvent(event, input);
    }


    public EventBus getEventBus() {
        return eventBus;
    }


    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
    }
}
